<?php

declare(strict_types=1);

namespace App\Controller\MchApi;

use App\Exception\XZXValidationException;
use App\Middleware\MchApi\MchJWTAuthMiddleware;
use App\Service\MchAccountService;
use App\Service\StatMonthlyTradeService;
use App\Service\SysExportLogService;
use App\Utils\CustomUtils;
use App\Utils\DateUtils;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Hyperf\Contract\TranslatorInterface;

/**
 * Class StatMonthlyTradeController
 *
 * @package App\Controller
 * @Controller(prefix="/mch/api/statMonthlyTrade")
 */
class StatMonthlyTradeController extends MchBaseController {

    /**
     * @Inject
     * @var TranslatorInterface
     */
    private $translator;

    /**
     * @Inject()
     * @var ValidatorFactoryInterface
     */
    protected $validationFactory;

    /**
     * @Inject()
     * @var StatMonthlyTradeService
     */
    protected $StatMonthlyTradeService;

    /**
     * @Inject()
     * @var SysExportLogService
     */
    protected $SysExportLogService;

    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;

    public function __construct (LoggerFactory $loggerFactory) {
        // 第一个参数对应日志的 name, 第二个参数对应 config/autoload/logger.php 内的 key
        $this->logger = $loggerFactory->get('log', 'default');
    }

    private function setLocale () {
        if ($this->request->header('locale') == 'en') {
            $this->translator->setLocale('en');
        }
    }

    /**
     * 查询
     * @PostMapping(path = "statList")
     * @Middleware(MchJWTAuthMiddleware::class)
     */
    public function statList (RequestInterface $request) {
        $this->setlocale();
        $validator = $this->validationFactory->make($request->all(), [
            'page'  => 'required|integer|min:1',
            'limit' => 'required|integer|min:1',
        ]);

        if ($validator->fails()) {
            // Handle exception
            $errorMessage = $validator->errors()->first();
            throw new XZXValidationException($errorMessage);
        }

        $param = $request->all();

        if (isset($param['search'])) {
            $search = $param['search'];
            CustomUtils::xzxAddSearch($param, $search, 'channelName');
            CustomUtils::xzxAddSearch($param, $search, 'mchName');
            CustomUtils::xzxAddSearch($param, $search, 'mchNo');
            CustomUtils::xzxAddSearch($param, $search, 'type');
            CustomUtils::xzxAddSearch($param, $search, 'statMonth');
            if (isset($param["statMonth"])) {
                if (!empty($param["statMonth"])) {
                    $param['statMonth'][0] = $param['statMonth'][0];
                    $param['statMonth'][1] = $param['statMonth'][1];
                }
                else {
                    unset($param['statMonth']);
                }
            }
        }

        $ext              = $this->request->getAttribute("ext");
        $params['source'] = 1;
        $param['mchId']   = $ext['mchId'];

        if ($param['type'] == 'mch') {
            return $this->StatMonthlyTradeService->statMchList($param);
        }
        else {
            return $this->StatMonthlyTradeService->statChannelList($param);
        }

    }

    /**
     * 查询
     * @PostMapping(path = "financeList")
     * @Middleware(MchJWTAuthMiddleware::class)
     */
    public function financeList (RequestInterface $request) {
        $this->setlocale();
        $validator = $this->validationFactory->make($request->all(), [
            'page'  => 'required|integer|min:1',
            'limit' => 'required|integer|min:1',
        ]);

        if ($validator->fails()) {
            // Handle exception
            $errorMessage = $validator->errors()->first();
            throw new XZXValidationException($errorMessage);
        }

        $param = $request->all();

        if (isset($param['search'])) {
            $search = $param['search'];
            CustomUtils::xzxAddSearch($param, $search, 'channelName');
            CustomUtils::xzxAddSearch($param, $search, 'mchName');
            CustomUtils::xzxAddSearch($param, $search, 'mchNo');
            CustomUtils::xzxAddSearch($param, $search, 'type');
            CustomUtils::xzxAddSearch($param, $search, 'statMonth');
            if (isset($param["statMonth"])) {
                if (!empty($param["statMonth"])) {
                    $param['statMonth'][0] = $param['statMonth'][0];
                    $param['statMonth'][1] = $param['statMonth'][1];
                }
                else {
                    unset($param['statMonth']);
                }
            }
        }

        if ($param['type'] == 'mch') {
            return $this->StatMonthlyTradeService->financeMchList($param);
        }
        else {
            return $this->StatMonthlyTradeService->financeChannelList($param);
        }
    }

    /**
     * 查询
     * @PostMapping(path = "setChannelSettleAmount")
     * @Middleware(AdminJWTAuthMiddleware::class)
     */
    public function setChannelSettleAmount (RequestInterface $request) {
        $this->setlocale();
        $validator = $this->validationFactory->make($request->all(), [
            'settleAmount' => 'required|integer|min:0',
        ]);

        if ($validator->fails()) {
            // Handle exception
            $errorMessage = $validator->errors()->first();
            throw new XZXValidationException($errorMessage);
        }

        $param = $request->all();
        return $this->StatMonthlyTradeService->setChannelSettleAmount($param);
    }

    /**
     * 查询
     * @PostMapping(path = "getTradeChannelList")
     * @Middleware(AdminJWTAuthMiddleware::class)
     */
    public function getTradeChannelList (RequestInterface $request) {
        $this->setlocale();
        $validator = $this->validationFactory->make($request->all(), [
            'page'  => 'required|integer|min:1',
            'limit' => 'required|integer|min:1',
        ]);

        if ($validator->fails()) {
            // Handle exception
            $errorMessage = $validator->errors()->first();
            throw new XZXValidationException($errorMessage);
        }

        $param = $request->all();

        if (isset($param['search'])) {
            $search = $param['search'];
            CustomUtils::xzxAddSearch($param, $search, 'channelId');
            CustomUtils::xzxAddSearch($param, $search, 'statMonth');
        }

        return $this->StatMonthlyTradeService->getTradeChannelList($param);

    }

    /**
     * 币种转换，损益计算
     * @PostMapping(path = "currencyTrans")
     * @Middleware(AdminJWTAuthMiddleware::class)
     */
    public function currencyTrans (RequestInterface $request) {
        $this->setlocale();
        $validator = $this->validationFactory->make($request->all(), [
            'id'   => 'required|uuid',
            'data' => 'required|array',
        ]);

        if ($validator->fails()) {
            // Handle exception
            $errorMessage = $validator->errors()->first();
            throw new XZXValidationException($errorMessage);
        }

        $param = $request->all();
        return $this->StatMonthlyTradeService->currencyTrans($param);

    }

    /**
     * 导出
     * @PostMapping(path = "statExportExcel")
     * @Middleware(MchJWTAuthMiddleware::class)
     *
     * @param RequestInterface $request
     *
     * @return array|mixed
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     * @throws \Throwable
     * @throws \TypeError
     */
    public function statExportExcel (RequestInterface $request) {
        $this->setlocale();
        $validator = $this->validationFactory->make($request->all(), []);

        if ($validator->fails()) {
            // Handle exception
            $errorMessage = $validator->errors()->first();
            throw new XZXValidationException($errorMessage);
        }

        $param = $request->all();

        $type = 5;

        // 新增导出记录
        $ext    = $this->request->getAttribute("ext");
        $result = $this->SysExportLogService->add(['type' => $type, 'createBy' => trim($ext['createBy'])]);


        // 直接把页数拖到很大
        $param['page']  = $request->post('page', 1);
        $param['limit'] = 10000000;
        $param['type']  = 'mch';
        $param['mchId'] = $ext['mchId'];

        if (isset($param['search'])) {
            $search = $param['search'];
            CustomUtils::xzxAddSearch($param, $search, 'mchName');
            CustomUtils::xzxAddSearch($param, $search, 'mchNo');
            CustomUtils::xzxAddSearch($param, $search, 'statMonth');
            if (isset($search["statMonth"])) {
                if (!empty($search["statMonth"])) {
                    $param['statMonth'][0] = $param['statMonth'][0];
                    $param['statMonth'][1] = $param['statMonth'][1];
                }
                else {
                    unset($param['statMonth']);
                }
            }
        }

        $logId    = $result['data'];
        $fileName = 'stat-' . $param['type'] . '-' . date('YmdHis') . rand(1000, 9999);
        if ($param['type'] == 'mch') {
            // 商户维度的统计
            $xlsCell = [
                ['filed' => 'statMonth',                    'name'  => trans('export.monthly-trade-mch.col.stat-month')],
                ['filed' => 'mchNo',                        'name'  => trans('export.monthly-trade-mch.col.mch-no')],
                ['filed' => 'mchName',                      'name'  => trans('export.monthly-trade-mch.col.mch-name')],
                ['filed' => 'floatSuccessSettleAmount',     'name'  => trans('export.monthly-trade-mch.col.settle-amount')],
                ['filed' => 'settleCurrency',               'name'  => trans('export.monthly-trade-mch.col.settle-currency')],
                ['filed' => 'successCount',                 'name'  => trans('export.monthly-trade-mch.col.success-count')],
                ['filed' => 'totalCount',                   'name'  => trans('export.monthly-trade-mch.col.total-count')],
                ['filed' => 'refundCount',                  'name'  => trans('export.monthly-trade-mch.col.refund-count')],
                ['filed' => 'disCount',                     'name'  => trans('export.monthly-trade-mch.col.dis-count')],
                ['filed' => 'riskCount',                    'name'  => trans('export.monthly-trade-mch.col.risk-count')],
                ['filed' => 'floatSuccessRate',             'name'  => trans('export.monthly-trade-mch.col.success-rate')],
                ['filed' => 'floatRefundRate',              'name'  => trans('export.monthly-trade-mch.col.refund-rate')],
                ['filed' => 'floatDisRate',                 'name'  => trans('export.monthly-trade-mch.col.dis-rate')],
            ];
        } else {
            // 渠道维度的统计
            $xlsCell = [
                ['filed' => 'statMonth',                    'name'  => '统计月份'],
                ['filed' => 'channelNo',                    'name'  => '渠道号'],
                ['filed' => 'channelName',                  'name'  => '渠道名称'],
                ['filed' => 'successCount',                 'name'  => '交易成功订单数'],
                ['filed' => 'totalCount',                   'name'  => '尝试交易订单数'],
                ['filed' => 'refundCount',                  'name'  => '退款订单数'],
                ['filed' => 'disCount',                     'name'  => '拒付订单数'],
                ['filed' => 'floatSuccessRate',             'name'  => '成功率'],
                ['filed' => 'floatRefundRate',              'name'  => '退款率'],
                ['filed' => 'floatDisRate',                 'name'  => '拒付率'],
            ];
        }

        $this->SysExportLogService->addToTask([
            'logId'    => $logId,
            'fileName' => $fileName,
            'type'     => $type,
            'param'    => $param,
            'xlsCell'  => $xlsCell,
            'locale'   => $this->translator->getLocale(),
        ]);

        return $result;
    }

    /**
     * 导出
     * @PostMapping(path = "financeExportExcel")
     * @Middleware(AdminJWTAuthMiddleware::class)
     *
     * @param RequestInterface $request
     *
     * @return array|mixed
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     * @throws \Throwable
     * @throws \TypeError
     */
    public function financeExportExcel (RequestInterface $request) {

        $validator = $this->validationFactory->make($request->all(), [
            'type' => 'required',
        ]);

        if ($validator->fails()) {
            // Handle exception
            $errorMessage = $validator->errors()->first();
            throw new XZXValidationException($errorMessage);
        }

        $param = $request->all();

        $type = 4;

        // 新增导出记录
        $ext    = $this->request->getAttribute("ext");
        $result = $this->SysExportLogService->add(['type' => $type, 'createBy' => trim($ext['createBy'])]);


        // 直接把页数拖到很大
        $param['page']  = trim($request->post('page', 1));
        $param['limit'] = 10000000;

        if (isset($param['search'])) {
            $search = $param['search'];
            CustomUtils::xzxAddSearch($param, $search, 'mchName');
            CustomUtils::xzxAddSearch($param, $search, 'mchNo');
        }

        $logId    = $result['data'];
        $fileName = 'finance-'.date('YmdHis').rand(1000, 9999);
        if ($param['type'] == 'mch') {
            // 商户维度的统计
            $xlsCell = [
                ['filed' => 'statMonth', 'name' => '统计月份'],
                ['filed' => 'mchNo', 'name' => '商户号'],
                ['filed' => 'mchName', 'name' => '商户名称'],
                ['filed' => 'floatMchTransAmount', 'name' => '商户尝试交易金额'],
                ['filed' => 'floatSuccessMchTransAmount', 'name' => '商户成功交易金额'],
                ['filed' => 'floatDisAmount', 'name' => '拒付金额'],
                ['filed' => 'floatRefundAmount', 'name' => '退款金额'],

                ['filed' => 'floatSettleAmount', 'name' => '结算金额'],
                ['filed' => 'floatServiceFee', 'name' => '交易手续费'],
                ['filed' => 'floatPerFee', 'name' => '单笔手续费'],
                ['filed' => 'floatFrozenAmount', 'name' => '冻结金额'],
                ['filed' => 'floatThawAmount', 'name' => '解冻金额'],
                ['filed' => 'floatBondAmount', 'name' => '平台保证金'],
                ['filed' => 'floatWithdrawFee', 'name' => '提现手续费'],
                ['filed' => 'floatTransFee', 'name' => '转账手续费'],
                ['filed' => 'floatRefundFee', 'name' => '单笔退款手续费'],
                ['filed' => 'floatDisFee', 'name' => '拒付处理费'],
                ['filed' => 'floatDisLookIntoFee', 'name' => '拒付调查费'],
                ['filed' => 'floatThreeDJudgeFee', 'name' => '3D判定费'],
                ['filed' => 'floatThreeDFee', 'name' => '3D手续费'],
                ['filed' => 'floatSalesCommission', 'name' => '销售提成'],
                ['filed' => 'floatEventFreezeAmount', 'name' => '事件冻结金额'],
                ['filed' => 'floatEventThawAmount', 'name' => '事件解冻金额'],
                ['filed' => 'floatEventDeductionAmount', 'name' => '事件扣款金额'],
                ['filed' => 'floatEventRechargeAmount', 'name' => '事件重置金额'],
            ];
        }
        else {
            // 渠道维度的统计
            $xlsCell = [
                ['filed' => 'statMonth', 'name' => '统计月份'],
                ['filed' => 'channelNo', 'name' => '渠道号'],
                ['filed' => 'channelName', 'name' => '渠道名称'],
                ['filed' => 'floatDisAmount', 'name' => '拒付金额'],
                ['filed' => 'floatRefundAmount', 'name' => '退款金额'],
                ['filed' => 'floatChannelTransAmount', 'name' => '结算金额'],
                ['filed' => 'floatServiceFee', 'name' => '交易手续费'],
                ['filed' => 'floatPerFee', 'name' => '单笔手续费'],
                ['filed' => 'floatFrozenAmount', 'name' => '冻结金额'],
                ['filed' => 'floatThawAmount', 'name' => '解冻金额'],
                ['filed' => 'floatBondAmount', 'name' => '平台保证金'],
                ['filed' => 'floatWithdrawFee', 'name' => '提现手续费'],
                ['filed' => 'floatTransFee', 'name' => '转账手续费'],
                ['filed' => 'floatRefundFee', 'name' => '单笔退款手续费'],
                ['filed' => 'floatDisFee', 'name' => '拒付处理费'],
                ['filed' => 'floatDisLookIntoFee', 'name' => '拒付调查费'],
                ['filed' => 'floatThreeDJudgeFee', 'name' => '3D判定费'],
                ['filed' => 'floatThreeDFee', 'name' => '3D手续费'],
            ];
        }

        $this->SysExportLogService->addToTask([
            'logId'    => $logId,
            'fileName' => $fileName,
            'type'     => $type,
            'param'    => $param,
            'xlsCell'  => $xlsCell,
        ]);

        return $result;
    }

}
